<?php
namespace WDB\Utils;

use     WDB;

class System
{
    /**
     * Redirects to a specified URL and terminates script.
     *
     * @param string|WebUI\Uri target url (should be fully qualified URL as HTTP
     *  header location requests
     * @param int HTTP code (301, 302...)
     */
    public static function redirect($url, $code = NULL)
    {
        if ($code != NULL)
        {
            header('HTTP/1.1 '.intval($code).' Redirect');
        }
        header('location: '.$url);
        die();
    }

    /**
     * Tries to find a class with multiple possible prefixes. Internal WDB utility,
     * used i.e. when user supplies own class for WDB interface (i.e. wrapper).
     * The class can be located in a particular namespace (WDB\Wrapper\User)
     * or just without it, having the exact passed name.
     *
     * @param string sought class name
     * @param string|array possible prefixes
     * @param bool allowed plain name with no prefix
     * @return string found class full name
     */
    public static function findClass($className, $prefixes, $noPrefix = TRUE)
    {
        if (!is_array($prefixes))
        {
            $prefixes = array($prefixes);
        }
        foreach ($prefixes as $prefix)
        {
            if (!is_string($prefix)) continue;
            $tClass = $prefix.$className;
            if (class_exists($tClass))
            {
                return $tClass;
            }
        }

        if ($noPrefix && class_exists($className))
        {
            return $className;
        }

        throw new WDB\Exception\ClassNotFound("class $className not found even with possible prefixes");

    }

    /**
     * Return is false:
     * -    Prints debug information about a variable and terminates script.
     * -    Does not do anything when config key 'debug' is not set to true.
     * Return is true:
     *      Returns the debug information as a string.
     * Supply function _wdb_external_debugger if you want to use an extra debugger
     *
     * @param mixed
     * @param bool
     * @param bool
     * @return string
     */
    public static function debug($val, $return = FALSE, $externalDebugger = TRUE)
    {
        if ($return || WDB\Config::read('debug'))
        {
            if ($return) ob_start();
            if ($externalDebugger && function_exists('_wdb_external_debugger'))
            {
                _wdb_external_debugger($val);
            }
            else
            {
                var_dump($val);
            }
            if ($return)
            {
                return ob_get_clean();
            }
            else
            {
                die();
            }
        }
    }

    /**
     * Returns first non-null argument (like MySQL COALESCE() function) or NULL if all arguments are NULL
     *
     * @param $value1,...
     * @return mixed
     */
    public static function coalesce()
    {
        foreach (func_get_args() as $arg)
        {
            if ($arg !== NULL) return $arg;
        }
        return NULL;
    }

    /**
     * Creates DateTime object from either timestamp or string representation or just passes-through DateTime object.
     *
     * @param string|int|\DateTime $value
     * @return \DateTime
     */
    public static function createDateTime($value)
    {
        if ($value instanceof \DateTime) return $value;
        if (is_null($value)) return NULL;
        if (is_numeric($value)) return \DateTime::createFromFormat ('U', $value);
        return new \DateTime($value);
    }
}
